﻿//At least one issue is left: very slow yet

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// 
    /// </summary>
    public class VerticalLines : BaseImageFilter
    {
        protected bool m_bReplaceColors = true;

        protected int nR = 10;
        protected int nG = 10;
        protected int nB = 10;

        /// <summary>
        /// Initializes a new instance of the <see cref="VerticalLines"/> class.
        /// </summary>
        public VerticalLines()
            : this(10, 10, 10, true)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="VerticalLines"/> class.
        /// </summary>
        /// <param name="_nR">The _n R.</param>
        /// <param name="_nG">The _n G.</param>
        /// <param name="_nB">The _n B.</param>
        /// <param name="_bReplaceColors">if set to <c>true</c> [_b replace colors].</param>
        public VerticalLines(int _nR, int _nG, int _nB, bool _bReplaceColors)
        {
            nR = _nR;
            nG = _nG;
            nB = _nB;
            m_bReplaceColors = _bReplaceColors;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="VerticalLines"/> class.
        /// </summary>
        /// <param name="_verticalLines">The _vertical lines.</param>
        internal VerticalLines(VerticalLines _verticalLines)
        {
            this.nR = _verticalLines.nR;
            this.nG = _verticalLines.nG;
            this.nB = _verticalLines.nB;
            this.m_bReplaceColors = _verticalLines.m_bReplaceColors;
        }

        public bool ReplaceColors
        {
            get { return m_bReplaceColors; }
            set { m_bReplaceColors = value; }
        }

        /// <summary>
        /// Gets or sets the R.
        /// </summary>
        /// <value>The R.</value>
        public int R
        {
            get { return nR; }
            set { nR = value; }
        }

        /// <summary>
        /// Gets or sets the G.
        /// </summary>
        /// <value>The G.</value>
        public int G
        {
            get { return nG; }
            set { nG = value; }
        }

        /// <summary>
        /// Gets or sets the B.
        /// </summary>
        /// <value>The B.</value>
        public int B
        {
            get { return nB; }
            set { nB = value; }
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmap = _bitmap;
            
            Dictionary<Point, Color> aColorPoint = new Dictionary<Point, Color>();

            Color colorToReplace = Color.Transparent;

            int nHeight = bitmap.Height;
            int nWidth = bitmap.Width;

            int x = 0;
            int y = 0;

            Color color1stRow = Color.Transparent;
            Color color2ndRow = Color.Transparent;
            for (x = 0; x < nWidth; x++)
            {
                for (y = 0; y < nHeight - 1; y++)
                {
                    color1stRow = bitmap.GetPixel(x, y);
                    color2ndRow = bitmap.GetPixel(x, y + 1);
                    if (ColorFunctions.IsInColorTolerance(color1stRow, color2ndRow, nR, nG, nB))
                    {
                        if (m_bReplaceColors)
                        {
                            colorToReplace = Color.White;
                        }
                        else
                        {
                            colorToReplace = color1stRow;
                        }
                        if (!aColorPoint.ContainsKey(new Point(x,y))) aColorPoint.Add(new Point(x, y), Color.White);
                        if (!aColorPoint.ContainsKey(new Point(x, y+1))) aColorPoint.Add(new Point(x, y + 1), Color.White);
                    }
                    else
                    {
                        if (!aColorPoint.ContainsKey(new Point(x, y))) aColorPoint.Add(new Point(x, y), Color.Black);
                        if (!aColorPoint.ContainsKey(new Point(x, y+1))) aColorPoint.Add(new Point(x, y + 1), Color.Black);
                    }
                }
            }

            //TODO: integrate this in upper for loops.
            foreach (KeyValuePair<Point, Color> keyValuePair in aColorPoint)
            {
                bitmap.SetPixel(keyValuePair.Key.X, keyValuePair.Key.Y, keyValuePair.Value);
            }
            return _bitmap;
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new VerticalLines(this);
        }
    }
}
